package com.bsg.upm.check;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.bsg.upm.constant.Messages;
import com.bsg.upm.constant.TaskDictConstants;
import com.bsg.upm.entity.DefinitionSubServUnitScaleEntity;
import com.bsg.upm.entity.ServEntity;
import com.bsg.upm.entity.SubServEntity;
import com.bsg.upm.entity.SubServSoftwareImageEntity;
import com.bsg.upm.entity.TaskEntity;

/**
 * 服务业务处理检查
 * 
 * @author HCK
 *
 */
@Service
public class ServCheck extends BaseCheck {

	/**
	 * 服务启动时检查
	 * 
	 * @param serv
	 *            服务对象
	 * @return CheckResult检查结果对象
	 */
	public CheckResult checkStart(ServEntity serv) {
		CheckResult chkRS = new CheckResult();
		// 存在性检查
		if (serv == null) {
			chkRS.setStatus(HttpStatus.SC_GONE);
			chkRS.setErrorMsg(MessageFormat.format(Messages.NOT_EXIST, "服务"));
			return chkRS;
		}

		// 判断是否创建成功
		TaskEntity createTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_CREATE);
		if (createTask == null || !TaskDictConstants.STATUS_CREATE_SUCCESS.equals(createTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("服务未创建成功，无法启动");
			return chkRS;
		}

		// 服务任务状态检查(任务未结束无法执行其他任务)
		TaskEntity task = taskDao.getLatestTaskByObjId(serv.getId());
		if (task != null && task.getEndDateTime() == null) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("该服务任务尚未结束，无法启动");
			return chkRS;
		}

		return chkRS;
	}

	/**
	 * 服务停止时检查
	 * 
	 * @param serv
	 *            服务对象
	 * @return CheckResult检查结果对象
	 */
	public CheckResult checkStop(ServEntity serv) {
		CheckResult chkRS = new CheckResult();
		// 存在性检查
		if (serv == null) {
			chkRS.setStatus(HttpStatus.SC_GONE);
			chkRS.setErrorMsg(MessageFormat.format(Messages.NOT_EXIST, "服务"));
			return chkRS;
		}

		// 判断是否创建成功
		TaskEntity createTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_CREATE);
		if (createTask == null || !TaskDictConstants.STATUS_CREATE_SUCCESS.equals(createTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("服务未创建成功，无法停止");
			return chkRS;
		}

		// 服务任务状态检查(任务未结束无法执行其他任务)
		TaskEntity task = taskDao.getLatestTaskByObjId(serv.getId());
		if (task != null && task.getEndDateTime() == null) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("该服务任务尚未结束，无法启动");
			return chkRS;
		}

		return chkRS;
	}

	/**
	 * 服务备份时检查
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return CheckResult检查结果对象
	 */
	public CheckResult checkBackup(Map<String, Object> paramMap) {
		CheckResult chkRS = new CheckResult();
		String servId = (String) paramMap.get("servId");

		// 服务存在性检查
		ServEntity serv = servDao.getBase(servId);
		if (serv == null) {
			chkRS.setStatus(HttpStatus.SC_GONE);
			chkRS.setErrorMsg(MessageFormat.format(Messages.NOT_EXIST, "服务"));
			return chkRS;
		}

		// 判断是否创建成功
		TaskEntity createTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_CREATE);
		if (createTask == null || !TaskDictConstants.STATUS_CREATE_SUCCESS.equals(createTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("服务未创建成功，无法备份");
			return chkRS;
		}

		// 是否允许备份
		boolean canBackup = false;
		List<SubServEntity> subServs = serv.getSubServs();
		for (SubServEntity subServ : subServs) {
			if (subServ.getSubOrder().getDefinitionSubServ().getCanBackup()) {
				canBackup = true;
				break;
			}
		}
		if (!canBackup) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("该类型服务无法备份");
			return chkRS;
		}

		// 服务任务状态检查(任务未结束无法执行其他任务)
		TaskEntity task = taskDao.getLatestTaskByObjId(servId);
		if (task != null && task.getEndDateTime() == null) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("该服务任务尚未结束，无法启动");
			return chkRS;
		}
		return chkRS;
	}

	/**
	 * 服务扩容时检查
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return CheckResult检查结果对象
	 */
	public CheckResult checkScaleUp(Map<String, Object> paramMap) {
		// 非逻辑检查
		CheckResult chkRS = checkScaleUpNonLogic(paramMap);
		if (chkRS.isError()) {
			return chkRS;
		}

		// 逻辑检查
		chkRS = checkScaleUpLogic(paramMap);
		if (chkRS.isError()) {
			return chkRS;
		}
		return chkRS;
	}

	/**
	 * 服务版本变更时检查
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return CheckResult检查结果对象
	 */
	public CheckResult checkUpdateImageVersion(Map<String, Object> paramMap) {
		// 非逻辑检查
		CheckResult chkRS = checkUpdateImageVersionNonLogic(paramMap);
		if (chkRS.isError()) {
			return chkRS;
		}

		// 逻辑检查
		chkRS = checkUpdateImageVersionLogic(paramMap);
		if (chkRS.isError()) {
			return chkRS;
		}
		return chkRS;
	}

	/**
	 * 服务重建时检查
	 * 
	 * @param serv
	 *            服务对象
	 * @return CheckResult检查结果对象
	 */
	public CheckResult checkRebuild(ServEntity serv) {
		CheckResult chkRS = new CheckResult();

		// 服务存在性检查
		if (serv == null) {
			chkRS.setStatus(HttpStatus.SC_GONE);
			chkRS.setErrorMsg(MessageFormat.format(Messages.NOT_EXIST, "服务"));
			return chkRS;
		}

		// 服务任务状态检查(任务未结束无法执行其他任务)
		TaskEntity task = taskDao.getLatestTaskByObjId(serv.getId());
		if (task != null && task.getEndDateTime() == null) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("该服务任务尚未结束，无法重建");
			return chkRS;
		}

		// 创建失败/未知时，才能重建
		TaskEntity createTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_CREATE);
		if (!TaskDictConstants.STATUS_CREATE_FAILURE.equals(createTask.getStatus())
				&& !TaskDictConstants.STATUS_UNKNOWN.equals(createTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("创建/扩容/版本变更失败/未知时，才能重建");
			return chkRS;
		}

		// 扩容失败/未知时，才能重建
		TaskEntity scaleUpTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_SCALE_UP);
		if (scaleUpTask != null) {
			if (!TaskDictConstants.STATUS_SCALE_UP_FAILURE.equals(scaleUpTask.getStatus())
					&& !TaskDictConstants.STATUS_UNKNOWN.equals(scaleUpTask.getStatus())) {
				chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
				chkRS.setErrorMsg("创建/扩容/版本变更失败/未知时，才能重建");
				return chkRS;
			}
		}

		// 版本变更失败/未知时，才能重建
		TaskEntity imageUpdateTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_IMAGE_UPDATE);
		if (imageUpdateTask != null) {
			if (!TaskDictConstants.STATUS_IMAGE_UPDATE_FAILURE.equals(imageUpdateTask.getStatus())
					&& !TaskDictConstants.STATUS_UNKNOWN.equals(imageUpdateTask.getStatus())) {
				chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
				chkRS.setErrorMsg("创建/扩容/版本变更失败/未知时，才能重建");
				return chkRS;
			}
		}

		return chkRS;
	}

	/**
	 * 服务删除时检查
	 * 
	 * @param serv
	 *            服务对象
	 * @return CheckResult检查结果对象
	 */
	public CheckResult checkRemove(ServEntity serv) {
		CheckResult chkRS = new CheckResult();

		// 服务存在性检查
		if (serv == null) {
			chkRS.setStatus(HttpStatus.SC_GONE);
			chkRS.setErrorMsg(MessageFormat.format(Messages.NOT_EXIST, "服务"));
			return chkRS;
		}

		// 服务任务状态检查(任务未结束无法执行其他任务)
		TaskEntity task = taskDao.getLatestTaskByObjId(serv.getId());
		if (task != null && task.getEndDateTime() == null) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("该服务任务尚未结束，无法删除");
			return chkRS;
		}

		return chkRS;
	}

	/**
	 * 扩容时非业务逻辑(非空和长度)检查
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return CheckResult检查结果对象
	 */
	@SuppressWarnings("unchecked")
	private CheckResult checkScaleUpNonLogic(Map<String, Object> paramMap) {
		CheckResult chkRS = new CheckResult();

		List<Map<String, Object>> dfSubServs_input = (List<Map<String, Object>>) paramMap.get("definitionSubServs");
		if (dfSubServs_input == null || dfSubServs_input.size() == 0) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("扩容参数错误");
			return chkRS;
		}

		for (Map<String, Object> map : dfSubServs_input) {
			String name = (String) map.get("name");
			if (StringUtils.isBlank(name)) {
				chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
				chkRS.setErrorMsg("扩容参数错误：必须指定子服务");
				return chkRS;
			}

			if (map.containsKey("scale")) {
				if (StringUtils.isBlank((String) map.get("scale"))) {
					chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
					chkRS.setErrorMsg("扩容参数错误：" + (String) map.get("name") + "规模不能为空");
					return chkRS;
				}
			}

			if (map.containsKey("dataDirSize")) {
				if (map.get("dataDirSize") == null) {
					chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
					chkRS.setErrorMsg("扩容参数错误：" + (String) map.get("name") + "数据容量不能为空");
					return chkRS;
				}
			}

			if (map.containsKey("networkBandwidth")) {
				if (map.get("networkBandwidth") == null) {
					chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
					chkRS.setErrorMsg("扩容参数错误：" + (String) map.get("name") + "带宽不能为空");
					return chkRS;
				}
			}
		}

		return chkRS;
	}

	/**
	 * 扩容时业务逻辑检查
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return CheckResult检查结果对象
	 */
	@SuppressWarnings("unchecked")
	private CheckResult checkScaleUpLogic(Map<String, Object> paramMap) {
		CheckResult chkRS = new CheckResult();

		String servId = (String) paramMap.get("servId");
		// 服务存在性检查
		ServEntity serv = servDao.getBase(servId);
		if (serv == null) {
			chkRS.setStatus(HttpStatus.SC_GONE);
			chkRS.setErrorMsg(MessageFormat.format(Messages.NOT_EXIST, "服务"));
			return chkRS;
		}

		// 判断是否创建成功
		TaskEntity createTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_CREATE);
		if (createTask == null || !TaskDictConstants.STATUS_CREATE_SUCCESS.equals(createTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("服务未创建成功，不能扩容");
			return chkRS;
		}

		// 服务任务状态检查(任务未结束不能执行其他任务)
		TaskEntity task = taskDao.getLatestTaskByObjId(serv.getId());
		if (task != null && task.getEndDateTime() == null) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("该服务任务尚未结束，无法扩容");
			return chkRS;
		}

		// 只有扩容成功时才能再次扩容
		TaskEntity scaleUpTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_SCALE_UP);
		if (task != null && !TaskDictConstants.STATUS_SCALE_UP_SUCCESS.equals(scaleUpTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("只有扩容成功时才能再次扩容");
			return chkRS;
		}

		// 软件版本变更未成功时，无法扩容
		TaskEntity imageUpdateTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_IMAGE_UPDATE);
		if (imageUpdateTask != null
				&& !TaskDictConstants.STATUS_IMAGE_UPDATE_SUCCESS.equals(imageUpdateTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("软件版本变更未成功时，无法扩容");
			return chkRS;
		}

		List<Map<String, Object>> dfSubServs_input = (List<Map<String, Object>>) paramMap.get("definitionSubServs");
		for (Map<String, Object> map : dfSubServs_input) {
			if (map.containsKey("scale")) {
				String scaleId = (String) map.get("scale");
				DefinitionSubServUnitScaleEntity scale = definitionSubServUnitScaleDao.get(scaleId);
				if (scale == null || !scale.getDefinitionSubServ().getName().equals(map.get("name"))) {
					chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
					chkRS.setErrorMsg("扩容参数错误：" + (String) map.get("name") + "规模不存在");
					return chkRS;
				}
			}
		}

		return chkRS;
	}

	/**
	 * 变更变更时非业务逻辑(非空和长度)检查
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return CheckResult检查结果对象
	 */
	@SuppressWarnings("unchecked")
	private CheckResult checkUpdateImageVersionNonLogic(Map<String, Object> paramMap) {
		CheckResult chkRS = new CheckResult();

		List<Map<String, Object>> dfSubServs_input = (List<Map<String, Object>>) paramMap.get("definitionSubServs");
		if (dfSubServs_input == null || dfSubServs_input.size() == 0) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("版本变更参数错误");
			return chkRS;
		}

		for (Map<String, Object> map : dfSubServs_input) {
			String name = (String) map.get("name");
			if (StringUtils.isBlank(name)) {
				chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
				chkRS.setErrorMsg("版本变更参数错误：必须指定子服务");
				return chkRS;
			}

			if (map.containsKey("softwareImage")) {
				if (StringUtils.isBlank((String) map.get("scale"))) {
					chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
					chkRS.setErrorMsg("版本变更参数错误：" + (String) map.get("name") + "软件版本不能为空");
					return chkRS;
				}
			}
		}

		return chkRS;
	}

	/**
	 * 版本变更时业务逻辑检查
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return CheckResult检查结果对象
	 */
	@SuppressWarnings("unchecked")
	private CheckResult checkUpdateImageVersionLogic(Map<String, Object> paramMap) {
		CheckResult chkRS = new CheckResult();

		String servId = (String) paramMap.get("servId");
		// 服务存在性检查
		ServEntity serv = servDao.getBase(servId);
		if (serv == null) {
			chkRS.setStatus(HttpStatus.SC_GONE);
			chkRS.setErrorMsg(MessageFormat.format(Messages.NOT_EXIST, "服务"));
			return chkRS;
		}

		// 判断是否创建成功
		TaskEntity createTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_CREATE);
		if (createTask == null || !TaskDictConstants.STATUS_CREATE_SUCCESS.equals(createTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
			chkRS.setErrorMsg("服务未创建成功，无法版本变更");
			return chkRS;
		}

		// 服务任务状态检查(任务未结束不能执行其他任务)
		TaskEntity task = taskDao.getLatestTaskByObjId(serv.getId());
		if (task != null && task.getEndDateTime() == null) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("该服务任务尚未结束，无法版本变更");
			return chkRS;
		}

		// 软件版本变更失败时，无法再次变更
		TaskEntity imageUpdateTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_IMAGE_UPDATE);
		if (imageUpdateTask != null
				&& !TaskDictConstants.STATUS_IMAGE_UPDATE_SUCCESS.equals(imageUpdateTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("软件版本变更未成功时，无法再次变更");
			return chkRS;
		}

		// 扩容失败时，无法版本变更
		TaskEntity scaleUpTask = taskDao.getLatestTaskByObjIdAndActionType(serv.getId(),
				TaskDictConstants.ACTION_TYPE_SCALE_UP);
		if (task != null && !TaskDictConstants.STATUS_SCALE_UP_SUCCESS.equals(scaleUpTask.getStatus())) {
			chkRS.setStatus(HttpStatus.SC_CONFLICT);
			chkRS.setErrorMsg("扩容未成功时，无法版本变更");
			return chkRS;
		}

		List<Map<String, Object>> dfSubServs_input = (List<Map<String, Object>>) paramMap.get("definitionSubServs");
		for (Map<String, Object> map : dfSubServs_input) {
			if (map.containsKey("softwareImage")) {
				String softwareImageId = (String) map.get("softwareImage");
				SubServSoftwareImageEntity image = subServSoftwareImageDao.get(softwareImageId);
				if (image == null
						|| !image.getDefinitionSubServSoftware().getDefinitionSubServName().equals(map.get("name"))) {
					chkRS.setStatus(HttpStatus.SC_BAD_REQUEST);
					chkRS.setErrorMsg("版本变更参数错误：" + (String) map.get("name") + "软件版本不存在");
					return chkRS;
				}

				if (!image.isEnabled()) {
					chkRS.setStatus(HttpStatus.SC_GONE);
					chkRS.setErrorMsg(MessageFormat.format(Messages.DISABLED_NOT_SELECT, "软件版本"));
					return chkRS;
				}
			}
		}

		return chkRS;
	}

}
